﻿using System;
using System.Reflection;

namespace IInject.Reflection
{
	public class Property : ReflectionWrapper<PropertyInfo>
	{
		private Method _getMethod;
		private Method _setMethod;

		#region Constructors

		public Property(PropertyInfo propertyInfo) : base(propertyInfo)
		{
		}

		#endregion

		#region Properties

		public override string Name
		{
			get
			{
				return WrappedItem.Name;
			}
		}

		public override Type Type
		{
			get
			{
				return WrappedItem.PropertyType;
			}
		}

		public bool CanRead
		{
			get
			{
				return WrappedItem.CanRead;
			}
		}

		public bool CanWrite
		{
			get
			{
				return WrappedItem.CanWrite;
			}
		}

		public virtual Method GetGetMethod()
		{
			return GetGetMethod(false);
		}

		public virtual Method GetGetMethod(bool nonPublic)
		{
			if (_getMethod == null)
			{
				_getMethod = new Method(WrappedItem.GetGetMethod(nonPublic));
			}

			return _getMethod;
		}

		public virtual Method GetSetMethod()
		{
			return GetSetMethod(false);
		}

		public virtual Method GetSetMethod(bool nonPublic)
		{
			if (_setMethod == null)
			{
				_setMethod = new Method(WrappedItem.GetSetMethod(nonPublic));
			}

			return _setMethod;
		}

		#endregion

		#region Methods

		public virtual void SetValue(object component, object propertyValue)
		{
			SetValue(component, propertyValue, null);
		}

		public virtual void SetValue(object component, object propertyValue, object[] index)
		{
			WrappedItem.SetValue(component, propertyValue, index);
		}

		public virtual object GetValue(object component)
		{
			return GetValue(component, null);
		}

		public virtual object GetValue(object component, object[] index)
		{
			return WrappedItem.GetValue(component, index);
		}

		#endregion
	}
}
